/**
 * 存储管理器实现 - 支持多种存储后端
 */

#include <xdevice/storage.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <pthread.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <dirent.h>

/* ========== 存储后端注册表 ========== */
static const xdevice_storage_ops_t* storage_ops_registry[4] = {NULL};

/* ========== 内存存储（用于快速测试） ========== */
typedef struct mock_device {
    char device_name[128];
    char* data;
    size_t size;
    struct mock_device* next;
} mock_device_t;

static mock_device_t* mock_devices = NULL;
static pthread_mutex_t mock_storage_lock = PTHREAD_MUTEX_INITIALIZER;

/* ========== 本地文件存储结构 ========== */
typedef struct {
    char base_dir[512];
    pthread_mutex_t lock;
} local_storage_context_t;

/* ========== 通用辅助函数 ========== */

static int ensure_directory(const char* path) {
    struct stat st = {0};
    if (stat(path, &st) == -1) {
        if (mkdir(path, 0755) == -1 && errno != EEXIST) {
            return XDEVICE_CORE_ERROR_IO;
        }
    }
    return XDEVICE_CORE_OK;
}

static void get_device_path(const char* base_dir, const char* device_name, char* path, size_t path_size) {
    snprintf(path, path_size, "%s/%s.xdev", base_dir, device_name);
}

/* ========== 内存存储辅助函数 ========== */

static mock_device_t* find_mock_device(const char* name) {
    mock_device_t* device = mock_devices;
    while (device) {
        if (strcmp(device->device_name, name) == 0) {
            return device;
        }
        device = device->next;
    }
    return NULL;
}

static mock_device_t* create_mock_device(const char* name, size_t size) {
    mock_device_t* device = malloc(sizeof(mock_device_t));
    if (!device) return NULL;
    
    strncpy(device->device_name, name, sizeof(device->device_name) - 1);
    device->device_name[sizeof(device->device_name) - 1] = '\0';
    device->size = size;
    device->data = calloc(1, size);
    device->next = mock_devices;
    
    if (!device->data) {
        free(device);
        return NULL;
    }
    
    mock_devices = device;
    return device;
}

/* ========== 存储管理器API实现 ========== */

xdevice_storage_backend_t* xdevice_storage_create(xdevice_storage_type_t type, const char* config) {
    if (type >= 4 || !storage_ops_registry[type] || !config) {
        return NULL;
    }
    
    xdevice_storage_backend_t* backend = calloc(1, sizeof(xdevice_storage_backend_t));
    if (!backend) {
        return NULL;
    }
    
    backend->type = type;
    backend->ops = storage_ops_registry[type];
    strncpy(backend->config_path, config, sizeof(backend->config_path) - 1);
    
    // 初始化后端
    if (backend->ops->init && backend->ops->init(backend, config) != XDEVICE_CORE_OK) {
        free(backend);
        return NULL;
    }
    
    backend->initialized = true;
    return backend;
}

void xdevice_storage_destroy(xdevice_storage_backend_t* backend) {
    if (!backend) return;
    
    if (backend->initialized && backend->ops && backend->ops->cleanup) {
        backend->ops->cleanup(backend);
    }
    
    free(backend);
}

int xdevice_storage_register(xdevice_storage_type_t type, const xdevice_storage_ops_t* ops) {
    if (type >= 4 || !ops) {
        return XDEVICE_CORE_ERROR_INVALID_PARAM;
    }
    
    storage_ops_registry[type] = ops;
    return XDEVICE_CORE_OK;
}

/* ========== 占位符存储后端实现 ========== */

/* ========== 本地文件存储实现 ========== */

/* ========== 本地文件存储实现 ========== */

static int local_init(xdevice_storage_backend_t* backend, const char* config) {
    if (!backend || !config) {
        return XDEVICE_CORE_ERROR_INVALID_PARAM;
    }
    
    // 为每个backend实例分配独立的上下文
    local_storage_context_t* ctx = malloc(sizeof(local_storage_context_t));
    if (!ctx) {
        printf("[Storage] 内存分配失败\n");
        return XDEVICE_CORE_ERROR_OUT_OF_MEMORY;
    }
    
    // 初始化上下文
    strncpy(ctx->base_dir, config, sizeof(ctx->base_dir) - 1);
    ctx->base_dir[sizeof(ctx->base_dir) - 1] = '\0';
    
    if (pthread_mutex_init(&ctx->lock, NULL) != 0) {
        free(ctx);
        printf("[Storage] 互斥锁初始化失败\n");
        return XDEVICE_CORE_ERROR_IO;
    }
    
    // 确保目录存在
    int result = ensure_directory(ctx->base_dir);
    if (result != XDEVICE_CORE_OK) {
        pthread_mutex_destroy(&ctx->lock);
        free(ctx);
        printf("[Storage] 本地存储初始化失败: %s, 错误: %s\n", config, strerror(errno));
        return result;
    }
    
    // 保存上下文到backend
    backend->private_data = ctx;
    
    printf("[Storage] 本地存储初始化成功: %s\n", config);
    return XDEVICE_CORE_OK;
}

static int local_cleanup(xdevice_storage_backend_t* backend) {
    if (!backend || !backend->private_data) {
        return XDEVICE_CORE_OK;
    }
    
    local_storage_context_t* ctx = (local_storage_context_t*)backend->private_data;
    pthread_mutex_destroy(&ctx->lock);
    free(ctx);
    backend->private_data = NULL;
    
    printf("[Storage] 本地存储清理完成\n");
    return XDEVICE_CORE_OK;
}

static int local_create_device(xdevice_storage_backend_t* backend, const char* name, uint64_t size) {
    if (!backend || !backend->private_data || !name) {
        return XDEVICE_CORE_ERROR_INVALID_PARAM;
    }
    
    local_storage_context_t* ctx = (local_storage_context_t*)backend->private_data;
    char device_path[1024];
    get_device_path(ctx->base_dir, name, device_path, sizeof(device_path));
    
    pthread_mutex_lock(&ctx->lock);
    
    // 检查文件是否已存在
    if (access(device_path, F_OK) == 0) {
        pthread_mutex_unlock(&ctx->lock);
        printf("[Storage] 设备文件已存在: %s\n", device_path);
        return XDEVICE_CORE_ERROR_EXISTS;
    }
    
    // 创建设备文件
    int fd = open(device_path, O_CREAT | O_WRONLY | O_EXCL, 0644);
    if (fd < 0) {
        pthread_mutex_unlock(&ctx->lock);
        printf("[Storage] 创建设备文件失败: %s, 错误: %s\n", device_path, strerror(errno));
        return XDEVICE_CORE_ERROR_IO;
    }
    
    // 预分配文件大小
    if (ftruncate(fd, size) != 0) {
        close(fd);
        unlink(device_path);  // 删除失败的文件
        pthread_mutex_unlock(&ctx->lock);
        printf("[Storage] 设置文件大小失败: %s, 错误: %s\n", device_path, strerror(errno));
        return XDEVICE_CORE_ERROR_IO;
    }
    
    close(fd);
    pthread_mutex_unlock(&ctx->lock);
    
    printf("[Storage] 本地设备创建成功: %s, 大小: %lu 字节\n", device_path, size);
    return XDEVICE_CORE_OK;
}

static int local_open_device(xdevice_storage_backend_t* backend, const char* name) {
    if (!backend || !backend->private_data || !name) {
        return XDEVICE_CORE_ERROR_INVALID_PARAM;
    }
    
    local_storage_context_t* ctx = (local_storage_context_t*)backend->private_data;
    char device_path[1024];
    get_device_path(ctx->base_dir, name, device_path, sizeof(device_path));
    
    // 检查文件是否存在
    if (access(device_path, F_OK) != 0) {
        printf("[Storage] 设备文件不存在: %s\n", device_path);
        return XDEVICE_CORE_ERROR_NOT_FOUND;
    }
    
    printf("[Storage] 本地设备打开: %s\n", device_path);
    return XDEVICE_CORE_OK;
}

static int local_close_device(xdevice_storage_backend_t* backend, const char* name) {
    if (!backend || !backend->private_data || !name) {
        return XDEVICE_CORE_ERROR_INVALID_PARAM;
    }
    
    local_storage_context_t* ctx = (local_storage_context_t*)backend->private_data;
    char device_path[1024];
    get_device_path(ctx->base_dir, name, device_path, sizeof(device_path));
    
    printf("[Storage] 本地设备关闭: %s\n", device_path);
    return XDEVICE_CORE_OK;
}

static int64_t local_read(xdevice_storage_backend_t* backend, const char* name, uint64_t offset, void* buffer, size_t length) {
    if (!backend || !backend->private_data || !name || !buffer) {
        return XDEVICE_CORE_ERROR_INVALID_PARAM;
    }
    
    local_storage_context_t* ctx = (local_storage_context_t*)backend->private_data;
    char device_path[1024];
    get_device_path(ctx->base_dir, name, device_path, sizeof(device_path));
    
    pthread_mutex_lock(&ctx->lock);
    
    // 打开设备文件
    int fd = open(device_path, O_RDONLY);
    if (fd < 0) {
        pthread_mutex_unlock(&ctx->lock);
        printf("[Storage] 打开设备文件失败: %s, 错误: %s\n", device_path, strerror(errno));
        return XDEVICE_CORE_ERROR_NOT_FOUND;
    }
    
    // 移动到指定偏移
    if (lseek(fd, offset, SEEK_SET) == -1) {
        close(fd);
        pthread_mutex_unlock(&ctx->lock);
        printf("[Storage] 定位文件偏移失败: %s, 偏移: %lu, 错误: %s\n", device_path, offset, strerror(errno));
        return XDEVICE_CORE_ERROR_IO;
    }
    
    // 读取数据
    ssize_t bytes_read = read(fd, buffer, length);
    close(fd);
    pthread_mutex_unlock(&ctx->lock);
    
    if (bytes_read < 0) {
        printf("[Storage] 读取数据失败: %s, 错误: %s\n", device_path, strerror(errno));
        return XDEVICE_CORE_ERROR_IO;
    }
    
    printf("[Storage] 本地读取成功: %s, 偏移: %lu, 长度: %zd\n", device_path, offset, bytes_read);
    return bytes_read;
}

static int64_t local_write(xdevice_storage_backend_t* backend, const char* name, uint64_t offset, const void* buffer, size_t length) {
    if (!backend || !backend->private_data || !name || !buffer) {
        return XDEVICE_CORE_ERROR_INVALID_PARAM;
    }
    
    local_storage_context_t* ctx = (local_storage_context_t*)backend->private_data;
    char device_path[1024];
    get_device_path(ctx->base_dir, name, device_path, sizeof(device_path));
    
    pthread_mutex_lock(&ctx->lock);
    
    // 打开设备文件
    int fd = open(device_path, O_WRONLY);
    if (fd < 0) {
        pthread_mutex_unlock(&ctx->lock);
        printf("[Storage] 打开设备文件失败: %s, 错误: %s\n", device_path, strerror(errno));
        return XDEVICE_CORE_ERROR_NOT_FOUND;
    }
    
    // 移动到指定偏移
    if (lseek(fd, offset, SEEK_SET) == -1) {
        close(fd);
        pthread_mutex_unlock(&ctx->lock);
        printf("[Storage] 定位文件偏移失败: %s, 偏移: %lu, 错误: %s\n", device_path, offset, strerror(errno));
        return XDEVICE_CORE_ERROR_IO;
    }
    
    // 写入数据
    ssize_t bytes_written = write(fd, buffer, length);
    close(fd);
    pthread_mutex_unlock(&ctx->lock);
    
    if (bytes_written < 0) {
        printf("[Storage] 写入数据失败: %s, 错误: %s\n", device_path, strerror(errno));
        return XDEVICE_CORE_ERROR_IO;
    }
    
    printf("[Storage] 本地写入成功: %s, 偏移: %lu, 长度: %zd\n", device_path, offset, bytes_written);
    return bytes_written;
}

static int local_sync(xdevice_storage_backend_t* backend, const char* name) {
    if (!backend || !backend->private_data || !name) {
        return XDEVICE_CORE_ERROR_INVALID_PARAM;
    }
    
    local_storage_context_t* ctx = (local_storage_context_t*)backend->private_data;
    char device_path[1024];
    get_device_path(ctx->base_dir, name, device_path, sizeof(device_path));
    
    pthread_mutex_lock(&ctx->lock);
    
    // 打开文件并同步
    int fd = open(device_path, O_WRONLY);
    if (fd < 0) {
        pthread_mutex_unlock(&ctx->lock);
        printf("[Storage] 同步时打开文件失败: %s, 错误: %s\n", device_path, strerror(errno));
        return XDEVICE_CORE_ERROR_NOT_FOUND;
    }
    
    int result = fsync(fd);
    close(fd);
    pthread_mutex_unlock(&ctx->lock);
    
    if (result != 0) {
        printf("[Storage] 文件同步失败: %s, 错误: %s\n", device_path, strerror(errno));
        return XDEVICE_CORE_ERROR_IO;
    }
    
    printf("[Storage] 本地同步成功: %s\n", device_path);
    return XDEVICE_CORE_OK;
}

static int local_get_device_info(xdevice_storage_backend_t* backend, const char* name, xdevice_device_info_t* info) {
    if (!backend || !backend->private_data || !name || !info) {
        return XDEVICE_CORE_ERROR_INVALID_PARAM;
    }
    
    local_storage_context_t* ctx = (local_storage_context_t*)backend->private_data;
    char device_path[1024];
    get_device_path(ctx->base_dir, name, device_path, sizeof(device_path));
    
    struct stat st;
    if (stat(device_path, &st) != 0) {
        printf("[Storage] 获取设备信息失败: %s, 错误: %s\n", device_path, strerror(errno));
        return XDEVICE_CORE_ERROR_NOT_FOUND;
    }
    
    // 填充设备信息
    strncpy(info->name, name, sizeof(info->name) - 1);
    info->name[sizeof(info->name) - 1] = '\0';
    info->size = st.st_size;
    info->block_size = XDEVICE_BLOCK_SIZE;
    info->storage_type = XDEVICE_STORAGE_LOCAL;
    info->readonly = (access(device_path, W_OK) != 0);
    info->created_time = st.st_ctime;
    info->modified_time = st.st_mtime;
    
    printf("[Storage] 获取设备信息成功: %s, 大小: %lu 字节\n", device_path, info->size);
    return XDEVICE_CORE_OK;
}

static int local_list_devices(xdevice_storage_backend_t* backend, char names[][XDEVICE_MAX_DEVICE_NAME], int max_count) {
    if (!backend || !backend->private_data || !names || max_count <= 0) {
        return XDEVICE_CORE_ERROR_INVALID_PARAM;
    }
    
    local_storage_context_t* ctx = (local_storage_context_t*)backend->private_data;
    pthread_mutex_lock(&ctx->lock);
    
    // 打开目录
    DIR* dir = opendir(ctx->base_dir);
    if (!dir) {
        pthread_mutex_unlock(&ctx->lock);
        printf("[Storage] 打开目录失败: %s, 错误: %s\n", ctx->base_dir, strerror(errno));
        return XDEVICE_CORE_ERROR_IO;
    }
    
    int count = 0;
    struct dirent* entry;
    
    // 遍历目录文件
    while ((entry = readdir(dir)) != NULL && count < max_count) {
        // 检查是否为.xdev文件
        char* ext = strrchr(entry->d_name, '.');
        if (ext && strcmp(ext, ".xdev") == 0) {
            // 提取设备名称（去掉.xdev扩展名）
            size_t name_len = ext - entry->d_name;
            if (name_len < XDEVICE_MAX_DEVICE_NAME) {
                strncpy(names[count], entry->d_name, name_len);
                names[count][name_len] = '\0';
                count++;
            }
        }
    }
    
    closedir(dir);
    pthread_mutex_unlock(&ctx->lock);
    
    printf("[Storage] 列出设备完成，找到 %d 个设备\n", count);
    return count;
}

/* ========== 内存存储实现（用于快速测试） ========== */

static int mock_init(xdevice_storage_backend_t* backend, const char* config) {
    (void)backend;  // Mock存储不需要backend参数
    (void)config;   // Mock存储不需要配置参数
    printf("[Storage] 内存存储初始化\n");
    return XDEVICE_CORE_OK;
}

static int mock_cleanup(xdevice_storage_backend_t* backend) {
    (void)backend;  // Mock存储不需要backend参数
    // 清理所有内存设备
    pthread_mutex_lock(&mock_storage_lock);
    while (mock_devices) {
        mock_device_t* device = mock_devices;
        mock_devices = device->next;
        free(device->data);
        free(device);
    }
    pthread_mutex_unlock(&mock_storage_lock);
    printf("[Storage] 内存存储清理完成\n");
    return XDEVICE_CORE_OK;
}

static int mock_create_device(xdevice_storage_backend_t* backend, const char* name, uint64_t size) {
    (void)backend;  // Mock存储不需要backend参数
    pthread_mutex_lock(&mock_storage_lock);
    
    // 检查设备是否已存在
    if (find_mock_device(name)) {
        pthread_mutex_unlock(&mock_storage_lock);
        printf("[Storage] 内存设备已存在: %s\n", name);
        return XDEVICE_CORE_ERROR_EXISTS;
    }
    
    // 创建新设备
    mock_device_t* device = create_mock_device(name, size);
    if (!device) {
        pthread_mutex_unlock(&mock_storage_lock);
        printf("[Storage] 内存设备创建失败: %s\n", name);
        return XDEVICE_CORE_ERROR_OUT_OF_MEMORY;
    }
    
    pthread_mutex_unlock(&mock_storage_lock);
    printf("[Storage] 内存设备创建成功: %s, 大小: %lu 字节\n", name, size);
    return XDEVICE_CORE_OK;
}

static int64_t mock_read(xdevice_storage_backend_t* backend, const char* name, uint64_t offset, void* buffer, size_t length) {
    (void)backend;  // Mock存储不需要backend参数
    pthread_mutex_lock(&mock_storage_lock);
    
    mock_device_t* device = find_mock_device(name);
    if (!device) {
        pthread_mutex_unlock(&mock_storage_lock);
        printf("[Storage] 内存设备不存在: %s\n", name);
        return XDEVICE_CORE_ERROR_NOT_FOUND;
    }
    
    // 检查读取范围
    if (offset >= device->size) {
        pthread_mutex_unlock(&mock_storage_lock);
        return 0;  // 读取超出范围，返回0字节
    }
    
    // 调整读取长度
    if (offset + length > device->size) {
        length = device->size - offset;
    }
    
    // 从内存中读取数据
    memcpy(buffer, device->data + offset, length);
    
    pthread_mutex_unlock(&mock_storage_lock);
    printf("[Storage] 内存读取成功: %s, 偏移: %lu, 长度: %zu\n", name, offset, length);
    return length;
}

static int64_t mock_write(xdevice_storage_backend_t* backend, const char* name, uint64_t offset, const void* buffer, size_t length) {
    (void)backend;  // Mock存储不需要backend参数
    pthread_mutex_lock(&mock_storage_lock);
    
    mock_device_t* device = find_mock_device(name);
    if (!device) {
        pthread_mutex_unlock(&mock_storage_lock);
        printf("[Storage] 内存设备不存在: %s\n", name);
        return XDEVICE_CORE_ERROR_NOT_FOUND;
    }
    
    // 检查写入范围
    if (offset >= device->size) {
        pthread_mutex_unlock(&mock_storage_lock);
        return XDEVICE_CORE_ERROR_INVALID_PARAM;
    }
    
    // 调整写入长度
    if (offset + length > device->size) {
        length = device->size - offset;
    }
    
    // 写入到内存
    memcpy(device->data + offset, buffer, length);
    
    pthread_mutex_unlock(&mock_storage_lock);
    printf("[Storage] 内存写入成功: %s, 偏移: %lu, 长度: %zu\n", name, offset, length);
    return length;
}

static int mock_sync(xdevice_storage_backend_t* backend, const char* name) {
    (void)backend;  // Mock存储不需要backend参数
    printf("[Storage] 内存同步: %s (无操作)\n", name);
    return XDEVICE_CORE_OK;
}

static int mock_open_device(xdevice_storage_backend_t* backend, const char* name) {
    (void)backend;  // Mock存储不需要backend参数
    pthread_mutex_lock(&mock_storage_lock);
    mock_device_t* device = find_mock_device(name);
    pthread_mutex_unlock(&mock_storage_lock);
    
    if (!device) {
        printf("[Storage] 内存设备不存在: %s\n", name);
        return XDEVICE_CORE_ERROR_NOT_FOUND;
    }
    
    printf("[Storage] 内存设备打开: %s\n", name);
    return XDEVICE_CORE_OK;
}

static int mock_close_device(xdevice_storage_backend_t* backend, const char* name) {
    (void)backend;  // Mock存储不需要backend参数
    printf("[Storage] 内存设备关闭: %s\n", name);
    return XDEVICE_CORE_OK;
}

static int mock_get_device_info(xdevice_storage_backend_t* backend, const char* name, xdevice_device_info_t* info) {
    (void)backend;  // Mock存储不需要backend参数
    if (!info) return XDEVICE_CORE_ERROR_INVALID_PARAM;
    
    pthread_mutex_lock(&mock_storage_lock);
    mock_device_t* device = find_mock_device(name);
    if (!device) {
        pthread_mutex_unlock(&mock_storage_lock);
        printf("[Storage] 内存设备不存在: %s\n", name);
        return XDEVICE_CORE_ERROR_NOT_FOUND;
    }
    
    // 填充设备信息
    strncpy(info->name, name, sizeof(info->name) - 1);
    info->name[sizeof(info->name) - 1] = '\0';
    info->size = device->size;
    info->block_size = XDEVICE_BLOCK_SIZE;
    info->storage_type = XDEVICE_STORAGE_MOCK;
    info->readonly = false;
    info->created_time = 0;  // 内存设备没有时间戳
    info->modified_time = 0;
    
    pthread_mutex_unlock(&mock_storage_lock);
    printf("[Storage] 获取内存设备信息成功: %s, 大小: %lu 字节\n", name, info->size);
    return XDEVICE_CORE_OK;
}

static int mock_list_devices(xdevice_storage_backend_t* backend, char names[][XDEVICE_MAX_DEVICE_NAME], int max_count) {
    (void)backend;  // Mock存储不需要backend参数
    if (!names || max_count <= 0) return XDEVICE_CORE_ERROR_INVALID_PARAM;
    
    pthread_mutex_lock(&mock_storage_lock);
    
    int count = 0;
    mock_device_t* device = mock_devices;
    
    while (device && count < max_count) {
        size_t len = strlen(device->device_name);
        if (len >= XDEVICE_MAX_DEVICE_NAME) len = XDEVICE_MAX_DEVICE_NAME - 1;
        memcpy(names[count], device->device_name, len);
        names[count][len] = '\0';
        count++;
        device = device->next;
    }
    
    pthread_mutex_unlock(&mock_storage_lock);
    printf("[Storage] 列出内存设备完成，找到 %d 个设备\n", count);
    return count;
}

/* ========== 存储后端操作表定义 ========== */

static const xdevice_storage_ops_t local_ops = {
    .init = local_init,
    .cleanup = local_cleanup,
    .create_device = local_create_device,
    .open_device = local_open_device,
    .close_device = local_close_device,
    .read = local_read,
    .write = local_write,
    .sync = local_sync,
    .get_device_info = local_get_device_info,
    .list_devices = local_list_devices
};

static const xdevice_storage_ops_t mock_ops = {
    .init = mock_init,
    .cleanup = mock_cleanup,
    .create_device = mock_create_device,
    .open_device = mock_open_device,
    .close_device = mock_close_device,
    .read = mock_read,
    .write = mock_write,
    .sync = mock_sync,
    .get_device_info = mock_get_device_info,
    .list_devices = mock_list_devices
};

/* ========== 存储后端注册函数 ========== */

int xdevice_storage_local_register(void) {
    return xdevice_storage_register(XDEVICE_STORAGE_LOCAL, &local_ops);
}

int xdevice_storage_mock_register(void) {
    return xdevice_storage_register(XDEVICE_STORAGE_MOCK, &mock_ops);
}

// 注意：NFS和NVMeoF后端尚未实现，暂时不支持注册
